// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SoundSourceComponent.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the SoundSourceComponent class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __SOUNDSOURCECOMPONENT_H__
#define __SOUNDSOURCECOMPONENT_H__

// Include files
#include "../../dependencies.h"
#ifdef __COMPILE_WITH_SFML_AUDIO__
#include "../../core/EntityComponent.h"


// SoundSourceComponent class
//! Component wrapper of SFML's sf::Sound and sf::Music.
//!
//! <b>XML:</b>
//! \code
//! <SoundSourceComponent>
//!    <!-- Properties -->
//! </SoundSourceComponent>
//! \endcode
class SoundSourceComponent : public EntityComponent
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    //! @param parent        The parent entity to which the component should be added.
    SoundSourceComponent(Entity *parent);
    //! Deconstructor
    ~SoundSourceComponent();

    // Methods
    //! Returns a direct pointer to the sf::Sound object in this component.
    //! @note Not available in AngelScript.
    sf::Sound* getSound();
    //! Returns a direct pointer to the sf::Music object in this component.
    //! @note Not available in AngelScript.
    sf::Music* getMusic();

    //! Loads the sound data as a music (streaming) object.
    //!
    //! <b>XML:</b>
    //! \code
    //! <music type="string" value="" />
    //! \endcode
    //!
    //! @param fileName      Filename of the music object to load.
    bool loadMusic(const std::string &fileName);
    //! Loads the sound data as a music (streaming) object from memory.
    //! @param buffer        Pointer to the start of the buffer.
    //! @param length        Length of the buffer.
    bool loadMusicFromMemory(c8 *buffer, long length);
    //! Loads the sound data from a sound buffer.
    //! @param bufferName    Name of the buffer to load.
    //! @see SoundManager
    bool loadSoundBuffer(const std::string &bufferName);

    //! Unloads previously loaded data.
    void unloadData();

    //! Plays the associated sound.
    void play();
    //! Pauses the associated sound.
    void pause();
    //! Stops the associated sound.
    void stop();

    //! Gets the attenuation of the sound.
    f32 getAttenuation() const;
    //! Returns whether the sound is paused.
    bool getIsPaused() const;
    //! Returns whether the sound is playing.
    bool getIsPlaying() const;
    //! Returns whether the sound has been stopped.
    bool getIsStopped() const;
    //! Gets the loop state of the sound.
    bool getLoop() const;
    //! Gets the minimum distance.
    f32 getMinDistance() const;
    //! Gets the current playing position of the sound.
    //! @note Only works when a sound buffer is loaded.
    f32 getOffset() const;
    //! Gets the pitch of the sound.
    f32 getPitch() const;
    //! Gets the volume of the sound.
    f32 getVolume() const;

    //! Sets the attenuation factor.
    //! The higher the attenuation, the more the sound will be attenuated with distance from
    //! listener.
    //!
    //! <b>XML:</b>
    //! \code
    //! <attenuation type="number" value="" />
    //! \endcode
    //!
    //! @param attenuation   New attenuation factor.
    void setAttenuation(f32 attenuation);
    //! Sets the sound loop state.
    //!
    //! <b>XML:</b>
    //! \code
    //! <loop type="bool" value="" />
    //! \endcode
    //!
    //! @param value         If true, the sound loops. Else the sound doesn't loop.
    void setLoop(bool value);
    //! Sets the minimum distance.
    //! Closer than this distance, the listener will hear the sound at its maximum volume.
    //!
    //! <b>XML:</b>
    //! \code
    //! <minDistance type="number" value="" />
    //! \endcode
    void setMinDistance(f32 minDistance);
    //! Sets the current playing position of the sound.
    //! @note Only works when a sound buffer is loaded.
    void setOffset(f32 offset);
    //! Sets the sound pitch.
    //!
    //! <b>XML:</b>
    //! \code
    //! <pitch type="number" value="" />
    //! \endcode
    //!
    void setPitch(f32 pitch);
    //! Sets the sound volume.
    //!
    //! <b>XML:</b>
    //! \code
    //! <volume type="number" value="" />
    //! \endcode
    //!
    void setVolume(f32 volume);

    // Events
    //! Updates the position of the component after its parent has been updated.
    //! @note For internal use only!
    void onPositionChange(void *p);
    //! Pauses the component if the parent is paused.
    //! @note For internal use only!
    void onPause(void *p);
    //! Unpauses the component if the parent is unpaused.
    //! @note For internal use only!
    void onUnPause(void *p);
    //! Responds to changes of the sound data attached to this component.
    //! @note For internal use only!
    void onSound(void *p);

    // Serialization
    //! Serializes this object.
    //! @param attributes
    virtual bool onSerialization(SerializedAttributes *attributes);
    //! Deserializes this object.
    //! @param attributes
    virtual bool onDeserialization(SerializedAttributes *attributes);

private:

    // Members
    sf::Sound *mSound;
    sf::Music *mMusic;

    c8 *mBuffer;
    long mBufferSize;
    std::string mSoundFileName;

    f32 mAttenuation;
    bool mLoop;
    f32 mMinDistance;
    f32 mPitch;
    vector3df mPosition;
    f32 mVolume;

    bool mWasPaused;

};

#endif // __COMPILE_WITH_SFML_AUDIO__

#endif
